package com.atguigu.auth.Service.impl;


import com.atguigu.auth.Service.SysMenuService;
import com.atguigu.auth.mapper.SysMenuMapper;

import com.atguigu.auth.mapper.SysRoleMenuMapper;
import com.atguigu.auth.utils.MenuHelper;
import com.atguigu.common.exception.GuiguException;
import com.atguigu.model.system.SysMenu;
import com.atguigu.model.system.SysRoleMenu;
import com.atguigu.vo.system.AssginMenuVo;
import com.atguigu.vo.system.MetaVo;
import com.atguigu.vo.system.RouterVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.atguigu.auth.Service.SysRoleMenuService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.beans.Transient;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>a
 * 菜单表 服务实现类
 * </p>
 *
 * @author atguigu
 * @since 2024-09-05
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {
@Autowired
private SysRoleMenuService sysRoleMenuService;
//    菜单列表接口
    @Override
    public List<SysMenu> findNodes() {
//        查询所有菜单的数据
        List<SysMenu> sysMenuList = baseMapper.selectList(null);

//        构建树形结构
        List<SysMenu> resultList =  MenuHelper.bulidTree(sysMenuList);

        return resultList;
    }

    //    删除菜单
    @Override
    public void removeMenuById(Long id) {
//        判断当前菜单是否有子菜单;
        LambdaQueryWrapper<SysMenu> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysMenu::getId, id);
        Integer count = baseMapper.selectCount(wrapper);
        if (count > 1) {
            throw new GuiguException(201 ,"当前菜单无法删除,因为有子菜单");
        }
        baseMapper.deleteById(id);
    }

//    查询所有菜单和角色分配
    @Override
    public List<SysMenu> findMenuByRoleId(Long roleId) {
//        查询所有菜单  添加条件status = 1    可用/不可用
        LambdaQueryWrapper<SysMenu> wrapperSysMenu = new LambdaQueryWrapper<>();
        wrapperSysMenu.eq(SysMenu::getStatus, 1);
        List<SysMenu> allSysMenuList = baseMapper.selectList(wrapperSysMenu);

//        根据角色id roleId查询角色关系表里面  角色id对应所有的菜单id
        LambdaQueryWrapper<SysRoleMenu> wrapperSysRoleMenu = new LambdaQueryWrapper<>();
        wrapperSysRoleMenu.eq(SysRoleMenu::getRoleId,roleId);
        List<SysRoleMenu> sysRoleMenuList = sysRoleMenuService.list(wrapperSysRoleMenu);

        //        根据获取菜单id  获取菜单对象
        List<Long> menuIdList = sysRoleMenuList.stream().map(c -> c.getMenuId()).collect(Collectors.toList());
//        拿着菜单id和所有菜单集合里面的id进行比较   相同封装/不同不封装
        allSysMenuList.stream().forEach(item -> {
            if (menuIdList.contains(item.getId())) {
                item.setSelect(true);
            }else {
                item.setSelect(false);
            }
        });
//        返回规定格式树形显示的菜单列表
        List<SysMenu> sysMenuList = MenuHelper.bulidTree(allSysMenuList);
        return sysMenuList;
    }

    //为角色分配菜单
    @Transactional
    @Override
    public void doAssign(AssginMenuVo assginMenuVo) {
//        根据角色id  删除菜单角色表分配的数据
        LambdaQueryWrapper<SysRoleMenu> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRoleMenu::getRoleId, assginMenuVo.getRoleId());
        sysRoleMenuService.remove(wrapper);
//        从参数获取角色新分配的菜单id列表 把每个id数据添加到菜单角色表
List<Long> menuIdList = assginMenuVo.getMenuIdList();
for (Long menuId : menuIdList) {
    if (StringUtils.isEmpty(menuId)) {
        continue;
    }
            SysRoleMenu sysRoleMenu = new SysRoleMenu();
            sysRoleMenu.setMenuId(menuId);
            sysRoleMenu.setRoleId(assginMenuVo.getRoleId());
            sysRoleMenuService.save(sysRoleMenu);
        }
    }

    @Override
    public List<RouterVo> findUserMenuListByUserId(Long userId) {
//        判断当前用户是否是管理员  userid = 1/0    是管理员/不是管理员
        List<SysMenu> sysMenuList = null;
        if (userId.longValue()==1) {
            //        是管理员    查询所有菜单列表
            LambdaQueryWrapper<SysMenu> wrapper= new LambdaQueryWrapper<>();
            wrapper.eq(SysMenu::getStatus,1);
            wrapper.orderByAsc(SysMenu::getSortValue);
            sysMenuList = baseMapper.selectList(wrapper);
        }else {
//        不是管理员   查询可操作界面
            //1        多表查询关系表 角色关系关系表    菜单表
           sysMenuList =  baseMapper.findMenuListByUserId(userId);
        }

//2        把擦查询出的数据列表   构建为路由结勾
//        构建树形结构
        List<SysMenu> sysMenuTreeList = MenuHelper.bulidTree(sysMenuList);
//       构建要求的结构
        List<RouterVo> routerList = this.buildMenus(sysMenuTreeList);
        return routerList;
        }

    private List<RouterVo> buildMenus(List<SysMenu> menus) {
//        创建list集合    存储数据
        List<RouterVo> routers = new ArrayList<>();
        for (SysMenu menu : menus) {
            RouterVo router = new RouterVo();
            router.setHidden(false);
            router.setAlwaysShow(false);
            router.setPath(getRouterPath(menu));
            router.setComponent(menu.getComponent());
            router.setMeta(new MetaVo(menu.getName(), menu.getIcon()));
            //下一层
            List<SysMenu> children = menu.getChildren();
//            判断    1显示  0不显示
            if (menu.getType().intValue() == 1){
                //加载出来下面的隐藏路由
                List<SysMenu> hiddenMenuList = children.stream()
                        .filter(item -> !StringUtils.isEmpty(item.getComponent()))
                        .collect(Collectors.toList());
//                隐藏路由
                for (SysMenu hiddenMenu : hiddenMenuList) {
                    RouterVo hiddenRouter = new RouterVo();
                    hiddenRouter.setHidden(true);
                    hiddenRouter.setAlwaysShow(false);
                    hiddenRouter.setPath(getRouterPath(hiddenMenu));
                    hiddenRouter.setComponent(hiddenMenu.getComponent());
                    hiddenRouter.setMeta(new MetaVo(hiddenMenu.getName(), hiddenMenu.getIcon()));
                    routers.add(hiddenRouter);
                }
            } else {
                if (!CollectionUtils.isEmpty(children)) {
                    if(children.size() > 0) {
                        router.setAlwaysShow(true);
                    }
                    router.setChildren(buildMenus(children));
                }
            }
            routers.add(router);
        }
        return routers;
    }

    /**
     * 获取路由地址
     *
     * @param menu 菜单信息
     * @return 路由地址
     */
    public String getRouterPath(SysMenu menu) {
        String routerPath = "/" + menu.getPath();
        if(menu.getParentId().intValue() != 0) {
            routerPath = menu.getPath();
        }
        return routerPath;
    }


    //    5.更具用户id获取用户可操作的按钮列表
    @Override
    public List<String> findUserPermsByUserId(Long userId) {
//        判断管理员
        List<SysMenu> sysMenuList = null;
        if (userId.longValue() == 1){
            //        是查询所有按钮列表
            LambdaQueryWrapper<SysMenu> wrapper= new LambdaQueryWrapper<>();
            wrapper.eq(SysMenu::getStatus,1);
            sysMenuList = baseMapper.selectList(wrapper);
        }else {
            //        不是  查询可操作的按钮列表
           sysMenuList = baseMapper.findMenuListByUserId(userId);
        }
        //        多表查询关系表 角色关系关系表    菜单表
List<String> permsList =  sysMenuList.stream()
                        .filter(item -> item.getType() == 2)
                        .map(item -> item.getPerms())
                        .collect(Collectors.toList());




//        从查询出来的数据里面  获取可以操作的按钮值的list集合 返回
        return permsList;
    }
}




